// ==UserScript==
// @name         Fullscreen Float Button
// @namespace    http://tampermonkey.net/
// @version      0.2
// @description  Add a floating button to switch fullscreen mode, only in top window.
// @author       You
// @match        *://*/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    function init() {
        // More intuitive icons for fullscreen and exit-fullscreen:
        const fullBtnText = '⬜️';
        const exitBtnText = '◻️';

        const css = `
            #fullscreen-float-button {
                position: fixed;
                top: 80px;
                right: 20px;
                z-index: 9999;
                width: 32px;
                height: 32px;
                background-color: rgba(0, 0, 0, 0.5);
                color: white;
                border: none;
                border-radius: 50%; /* Make it circular */
                cursor: grab;
                box-shadow: 0 2px 5px rgba(0,0,0,0.2);
                font-size: 16px;
                user-select: none;
                /* Center the icon */
                display: flex;
                align-items: center;
                justify-content: center;
                padding: 0;
                line-height: 1; /* Ensure vertical centering of the character */
                transition: transform 0.15s, box-shadow 0.15s;
            }
            #fullscreen-float-button:hover {
                box-shadow: 0 4px 10px rgba(0,0,0,0.3);
            }
            #fullscreen-float-button.dragging {
                cursor: grabbing;
                transform: scale(0.95);
                box-shadow: 0 2px 5px rgba(0,0,0,0.2); /* Keep shadow consistent during drag */
            }
        `;

        const styleSheet = document.createElement("style");
        styleSheet.innerText = css;
        document.head.appendChild(styleSheet);

        const fullscreenButton = document.createElement('div');
        fullscreenButton.id = 'fullscreen-float-button';
        fullscreenButton.textContent = fullBtnText;

        document.body.appendChild(fullscreenButton);

        // 检查当前是否处于全屏状态的函数
        function isFullscreen() {
            return document.fullscreenElement ||
                   document.mozFullScreenElement ||
                   document.webkitFullscreenElement ||
                   document.msFullscreenElement;
        }

        // 切换全屏的函数
        function toggleFullScreen() {
            if (!isFullscreen()) {
                if (document.documentElement.requestFullscreen) {
                    document.documentElement.requestFullscreen();
                } else if (document.documentElement.mozRequestFullScreen) { // Firefox
                    document.documentElement.mozRequestFullScreen();
                } else if (document.documentElement.webkitRequestFullscreen) { // Chrome, Safari and Opera
                    document.documentElement.webkitRequestFullscreen();
                } else if (document.documentElement.msRequestFullscreen) { // IE/Edge
                    document.documentElement.msRequestFullscreen();
                }
            } else {
                if (document.exitFullscreen) {
                    document.exitFullscreen();
                } else if (document.mozCancelFullScreen) { // Firefox
                    document.mozCancelFullScreen();
                } else if (document.webkitExitFullscreen) { // Chrome, Safari and Opera
                    document.webkitExitFullscreen();
                } else if (document.msExitFullscreen) { // IE/Edge
                    document.msExitFullscreen();
                }
            }
        }

        // 监听全屏状态变化，更新按钮文本
        document.addEventListener('fullscreenchange', updateButtonText);
        document.addEventListener('webkitfullscreenchange', updateButtonText);
        document.addEventListener('mozfullscreenchange', updateButtonText);
        document.addEventListener('MSFullscreenChange', updateButtonText);

        function updateButtonText() {
            if (isFullscreen()) {
                fullscreenButton.textContent = exitBtnText;
            } else {
                fullscreenButton.textContent = fullBtnText;
            }
        }
        updateButtonText(); // 初始加载时更新一次

        // --- 拖动逻辑 ---
        let isDragging = false;
        let hasDraggedSignificantDistance = false; // 是否已发生有意义的拖动
        let offsetX, offsetY; // 鼠标/触摸点相对于按钮左上角的偏移
        let initialMoveCheckX, initialMoveCheckY; // 用于拖拽阈值判断的初始位置
        const DRAG_THRESHOLD = 5; // 至少拖动5像素才算作有效拖动

        function dragStart(e) {
            // e.preventDefault() is called to prevent text selection and page scrolling.
            // On touch devices, this may prevent the 'click' event from firing.
            e.preventDefault();
            isDragging = true;
            hasDraggedSignificantDistance = false;
            fullscreenButton.classList.add('dragging');

            // 判断是触摸事件还是鼠标事件
            const clientX = e.type === 'touchstart' ? e.touches[0].clientX : e.clientX;
            const clientY = e.type === 'touchstart' ? e.touches[0].clientY : e.clientY;

            initialMoveCheckX = clientX; // 记录用于拖拽阈值判断的初始点
            initialMoveCheckY = clientY;

            const rect = fullscreenButton.getBoundingClientRect();
            offsetX = clientX - rect.left;
            offsetY = clientY - rect.top;

            // 确保按钮使用 left/top 定位以便拖动计算
            // getComputedStyle 用于获取最终应用的样式值
            if (getComputedStyle(fullscreenButton).position === 'fixed') {
                // 如果按钮当前是通过 right/bottom 定位的，则转换为 left/top
                if (fullscreenButton.style.right !== 'auto' || fullscreenButton.style.bottom !== 'auto') {
                    fullscreenButton.style.left = rect.left + 'px';
                    fullscreenButton.style.top = rect.top + 'px';
                    fullscreenButton.style.right = 'auto';
                    fullscreenButton.style.bottom = 'auto';
                }
            }

            if (e.type === 'mousedown') {
                document.addEventListener('mousemove', dragMove);
                document.addEventListener('mouseup', dragEnd);
            } else if (e.type === 'touchstart') {
                // { passive: false } 允许在 touchmove 中调用 e.preventDefault()
                document.addEventListener('touchmove', dragMove, { passive: false });
                document.addEventListener('touchend', dragEnd);
            }
        }

        function dragMove(e) {
            if (!isDragging) return;

            // 对于触摸移动，也需要阻止默认行为
            if (e.type === 'touchmove') {
                e.preventDefault();
            }

            const clientX = e.type === 'touchmove' ? e.touches[0].clientX : e.clientX;
            const clientY = e.type === 'touchmove' ? e.touches[0].clientY : e.clientY;

            // 检查是否拖动超过阈值
            if (!hasDraggedSignificantDistance) {
                const dx = Math.abs(clientX - initialMoveCheckX);
                const dy = Math.abs(clientY - initialMoveCheckY);
                if (dx > DRAG_THRESHOLD || dy > DRAG_THRESHOLD) {
                    hasDraggedSignificantDistance = true;
                }
            }

            let newLeft = clientX - offsetX;
            let newTop = clientY - offsetY;

            const buttonWidth = fullscreenButton.offsetWidth;
            const buttonHeight = fullscreenButton.offsetHeight;

            // 边界检查，防止按钮拖出视窗
            if (newLeft < 0) newLeft = 0;
            if (newTop < 0) newTop = 0;
            if (newLeft + buttonWidth > window.innerWidth) newLeft = window.innerWidth - buttonWidth;
            if (newTop + buttonHeight > window.innerHeight) newTop = window.innerHeight - buttonHeight;

            fullscreenButton.style.left = newLeft + 'px';
            fullscreenButton.style.top = newTop + 'px';
        }

        function dragEnd(e) {
            if (!isDragging) return;
            isDragging = false;
            fullscreenButton.classList.remove('dragging');

            if (e.type === 'mouseup') {
                document.removeEventListener('mousemove', dragMove);
                document.removeEventListener('mouseup', dragEnd);
            } else if (e.type === 'touchend') {
                document.removeEventListener('touchmove', dragMove);
                document.removeEventListener('touchend', dragEnd);
            }
        }

        // 为按钮添加拖动相关的事件监听器 (鼠标和触摸)
        fullscreenButton.addEventListener('mousedown', dragStart);
        fullscreenButton.addEventListener('touchstart', dragStart, { passive: false });

        fullscreenButton.addEventListener('click', (e) => {
            // On touch devices, this click event may not fire if preventDefault() was called on touchstart.
            // On mouse devices, this correctly distinguishes between a click and a drag.
            if (hasDraggedSignificantDistance) {
                // It was a drag, so we do nothing.
                return;
            }
            toggleFullScreen();
        });

        // Handler for taps on touch devices.
        fullscreenButton.addEventListener('touchend', (e) => {
            if (hasDraggedSignificantDistance) {
                // This was a drag, do not toggle.
                return;
            }
            // This was a tap.
            e.preventDefault(); // Prevent synthetic click event.
            toggleFullScreen();
        });
    }

    if (window.self === window.top) {
        init();
    }
})();
